package org.fireflow2.designer.eclipse.commands.connection;

import java.util.List;
import java.util.UUID;

import org.eclipse.gef.commands.Command;
import org.fireflow.pdl.fpdl20.diagram.TransitionShape;
import org.fireflow.pdl.fpdl20.diagram.WorkflowNodeShape;
import org.fireflow.pdl.fpdl20.diagram.basic.Line;
import org.fireflow.pdl.fpdl20.diagram.basic.impl.PointImpl;
import org.fireflow.pdl.fpdl20.diagram.impl.TransitionShapeImpl;
import org.fireflow.pdl.fpdl20.process.Node;
import org.fireflow.pdl.fpdl20.process.SubProcess;
import org.fireflow.pdl.fpdl20.process.Transition;
import org.fireflow.pdl.fpdl20.process.impl.TransitionImpl;
import org.fireflow2.designer.eclipse.modelwrapper.NodeWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.SubProcessWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.basic.TransitionWrapper;

public class CreateTransitionCommand extends Command {
	NodeWrapper source = null;
	NodeWrapper target = null;
	TransitionWrapper transitionWrapper = null;
	SubProcessWrapper subProcessWrapper = null;
//	GroupWrapper parentWrapper = null;
	//下面的属性应该不需要
//	boolean connectTowActivity = false;// 是否连接两个activity
//	RouterWrapper synchronizerWrapper = null;
//	TransitionWrapper transitionWrapper2 = null;
	

	public void setSource(NodeWrapper source) {
		this.source = source;
	}

	public void setTarget(NodeWrapper target) {
		this.target = target;
	}

	public NodeWrapper getSource() {
		return source;
	}

	public NodeWrapper getTarget() {
		return target;
	}
	
//	public void setGroupWrapper(GroupWrapper parentWrapper){
//		this.groupWrapper = parentWrapper;
//	}
	
	public void setSubProcessWrapper(SubProcessWrapper subProcessWp){
		this.subProcessWrapper = subProcessWp;
	}

//	public boolean isConnectTowActivity() {
//		return connectTowActivity;
//	}
//
//	public void setConnectTowActivity(boolean connectTowActivity) {
//		this.connectTowActivity = connectTowActivity;
//	}

	public void execute() {		
		
		SubProcess subProcess = (SubProcess) (subProcessWrapper)
				.getWorkflowModelElement();
		String name = findANewTransitionName(subProcess);
		Transition transition = new TransitionImpl(subProcess, name,
				(Node) source.getWorkflowModelElement(), (Node) target
						.getWorkflowModelElement());
		((Node)source.getWorkflowModelElement()).getLeavingTransitions().add(transition);
		((Node)target.getWorkflowModelElement()).getEnteringTransitions().add(transition);
		
		String shapeId = UUID.randomUUID().toString();
		TransitionShape transitionShape = new TransitionShapeImpl(shapeId);
		transitionShape.setWorkflowElementRef(transition.getId());
		transitionShape.setFromWorkflowNodeShape((WorkflowNodeShape)source.getDiagramElement());
		transitionShape.setToWorkflowNodeShape((WorkflowNodeShape)target.getDiagramElement());
		((Line)transitionShape.getShape()).setLabelPosition(new PointImpl(0,0));
		
		transitionWrapper = new TransitionWrapper(subProcessWrapper,transition,transitionShape);
		
		transitionWrapper.setSource(source);
		transitionWrapper.setTarget(target);
		
		source.addLeavingTransition(transitionWrapper);
		target.addEnteringTransition(transitionWrapper);
		
		subProcessWrapper.addChild(transitionWrapper);
	}

	private String findANewTransitionName(SubProcess subflow){
		boolean exist = true;
		int n = 1;
		List transitions = subflow.getTransitions();
		String name = "Transition"
			+ (transitions.size() + n);		
		while(exist){
			boolean found = false;
			for (int i=0;i<transitions.size();i++){
				Transition transition = (Transition)transitions.get(i);
				if (name.equals(transition.getName())){
					n++;
					name = "Transition"
						+ (transitions.size() + n);
					found = true;
					break;
				}
			}
			if (!found){
				exist=false;
			}
		}
		return name;
	}
	
	public void redo() {
		((Node)source.getWorkflowModelElement()).getLeavingTransitions()
			.add((Transition)transitionWrapper.getWorkflowModelElement());
		((Node)target.getWorkflowModelElement()).getEnteringTransitions()
			.add((Transition)transitionWrapper.getWorkflowModelElement());
		
		transitionWrapper.setSource(source);
		transitionWrapper.setTarget(target);
		source.addLeavingTransition(transitionWrapper);
		target.addEnteringTransition(transitionWrapper);
		subProcessWrapper.addChild(transitionWrapper);

	}

	public void undo() {
		((Node)source.getWorkflowModelElement()).getLeavingTransitions()
			.remove((Transition)transitionWrapper.getWorkflowModelElement());
		((Node)target.getWorkflowModelElement()).getEnteringTransitions()
			.remove((Transition)transitionWrapper.getWorkflowModelElement());
		source.removeLeavingTransition(transitionWrapper);
		target.removeEnteringTransition(transitionWrapper);

		transitionWrapper.setSource(null);
		transitionWrapper.setTarget(null);

		subProcessWrapper.deleteChild(transitionWrapper);

	}
}
